const fs = require("fs");
const path = require("path");
const AppConfig = require("$config/app.config");
const db = require("@/db/mysql");
const BaseTaskScheduler = require("./base-task-scheduler");

// 文件存储有效期，10分钟
const EXPIRED_RANGE_TIME = AppConfig.FILE_EXPIRED_TIME;
// cron规则
const CRON_PATTERN = "*/30 * * * *";
// 清空未使用的文件
const clearNotBindFileTask = new BaseTaskScheduler();

/**
 * 任务运行
 * 1、查询出未绑定业务的文件；
 * 2、将数据库中的状态字段改为：失效；
 * 3、清空本地文件；
 */
const TaskHandler = async () => {
	try {
		console.log("定时任务执行中-删除未绑定业务的文件");
		const SQL = `SELECT id, path, create_time FROM file_files WHERE is_lock = 0 AND status = 0`;
		const SET_EXPIRED_SQL = ids => `UPDATE file_files SET status = 1 WHERE id in (${ids})`; // 设置过期SQL
		const { code, results } = await db.query(SQL);
		if (code === 200 && Array.isArray(results) && results.length > 0) {
			const notBindFiles = [];
			// 取出过期的文件
			results.forEach(file => {
				const now = Date.now();
				const createTime = new Date(file.create_time).getTime(); // 文件创建时间
				// 判断是否在有效期内
				if (now - createTime > EXPIRED_RANGE_TIME) {
					notBindFiles.push(file);
				}
			});
			if (notBindFiles.length > 0) {
				const idsStr = notBindFiles.map(file => "'" + file.id + "'").join(", ");
				const updateResult = await db.query(SET_EXPIRED_SQL(idsStr));
				if (updateResult.code === 200 && updateResult.results.changedRows > 0) {
					const deleteFilePaths = notBindFiles.map(file => path.join("./" + file.path));
					_deleteFiles(deleteFilePaths);
				}
			}
		}
	} catch (error) {
		console.log("定时清空未使用的文件异常: ", error);
	}
};

/**
 * 删除文件
 * @param {*} paths
 */
const _deleteFiles = paths => {
	paths.forEach(p => {
		try {
			(filePath => {
				console.log("正在删除过期附件：", filePath);
				fs.access(filePath, fs.constants.F_OK, err => {
					if (err) {
						console.log(`文件【${filePath}】不存在`);
						return;
					}
					fs.unlink(filePath, err => {
						if (err) {
							console.log("过期附件删除失败: ", error);
							return;
						}
						console.log(`过期附件：${p} 已删除`);
					});
				});
			})(p);
		} catch (error) {
			console.log("删除过期的附件异常: ", error);
		}
	});
};

// 创建一个30分钟执行一次的任务
clearNotBindFileTask.createJob(CRON_PATTERN, TaskHandler, { initExecute: true });

module.exports = clearNotBindFileTask;
